<?php

/** 
 * Agrupa a un conjunto de paquetes y mantiene cuenta del precio
 * total que implicaria adquirirlos todos.
 * 
 * @package    AltargetEcommerce
 * @subpackage model
 * @author     Carlo Lopez <carlo.xavier.lopez 'en' gmail 'punto' com>
 */
class Carrito
{
  // Invariante: no existen en el carrito dos paquetes que tengan productos del mismo nombre
  protected $paquetes = array(); 
  
  protected $precio_total = 0; 

  protected $pago = null;

  /**
   * Instancia un carrito vacio.
   */
  public function __construct()
  {
    $this->paquetes = array();
    $this->precio_total = 0;
  }

  /**
   * Representacion en texto de un paquete.
   */
  public function __toString()
  {
    //TODO
  }

  /**
   * Devuelve el precio que suman los precios
   * individuales de cada paquete que este dentro 
   * del carrito.
   *
   * @return integer El precio total.
   */
  public function getPrecioTotal()
  {
    return $this->precio_total;
  }

  /*
   * Devuelve 1 en caso de agregarse efectivamente el paquete, o en caso
   * de ya existir el producto en el carrito de compras entonces
   * devuelve 0.
   *
   * @param $paquete Paquete El paquete que se agregara
   *
   */
  public function addPaquete(Paquete $paquete )
  {
    if($this->tieneProducto($paquete->getProducto()->getNombre()))
      return 0;
    array_push($this->paquetes, $paquete);
    return 1;
  }

/* TODO: Tal vez sea conveniente tener un metodo updatePaquete
         para usar cuando se modifica un elemento del carrito.
  public function updateProducto($nombreprod, array $reglas, $frec)
  {
    $posprod = $this->getProdPosNom($nombreprod);
    $this->productos[$posprod]['costo'] = 0;

    unset($this->frecuenc);
    $this->frecuen = array();
    $this->frecuen['id'] = $frec;
    unset($this->servicios[$posprod]);
    $this->servicios[$posprod] = array();
    $this->servicios[$posprod]['numserv'] = 0;

    unset($this->reglas[$posprod]);
    $this->reglas[$posprod] = array();

    $this->addReglas($posprod, $reglas);
  }
*/

  /**
   * Devuelve el pago que se hubiere hecho,
   * en caso de aplicar, de los servicios.
   *
   * @return   Pago El pago que se hubiere hecho por los productos 
   *                en el carrito.
   */
  public function getPago()
  {
    return $this->pago;
  }

  public function tienePago()
  {
    return isset($this->pago);
  }

  /*
   * Devuelve los paquetes que estan dentro del carrito.
   */
  public function getPaquetes()
  {
    return $this->paquetes;
  }

  /**
   * Devuelve el paquete, en caso de haberlo dentro del carrito,
   * que tenga un producto con el nombre $nombreprod.
   *
   * @param $nombreprod string El nombre del producto cuyo 
   *                           paquete se busca.
   */
  public function getPaquete($nombreprod)
  {
    foreach($this->paquetes as $paquete)
      if( !strcmp($paquete->getProducto()->getNombre(), $nombreprod) )
        return $paquete;
  }


  /*
   * dada la posicion del producto en el carrito, se devuelve
   * el conjunto de reglas asociadas al producto, en forma de 
   * parametros para la solicitud.
   */
  public function getAllRfrom($prodpos)
  {
    $result = array();
    $posserv = 0; 
    foreach($this->reglas[$prodpos] as $servic)
    {  
      //foreach($servic as $reglas)
       
        for($numregla = 0; $numregla < $servic['numreglas'] ; $numregla++)
          $result['regla_' . $this->servicios[$prodpos][$posserv]['nombre'] . '_' . $numregla] = $servic[$numregla]['id'];
        
        //$temp = $reglas;
        //unset($temp['numreglas']);
        //$result = array_merge($result, $temp);
      $posserv++;
    }
    return $result;
  }

  /*
   * Se saca un paquete del carrito de compras.
   *
   * @param $nomprod string  El nombre del producto del paquete
   *                         que se quiere sacar.
   * @return         boolean Devuelve true en caso de haberse sacado el paquete
   *                         de forma efectiva, devuelve false en caso de no exisir el paquete
   *                         dentro del carrito.
   */
  public function removePaquete($nomprod)
  {
    foreach($this->paquetes as $key => $paquete)
      if(!strcmp($paquete->getProducto()->getNombre(), $nomprod) )
      {
        unset($this->paquetes[$key]);
        //$this->reindexar($this->paquetes,$i);
        return true;
      }
    return false;  
  }

  /**
   * Establece el pago por los productos en el carrito.
   */
  public function setPago(Pago $pag)
  {
    $this->pago = $pag;
  }

  /**
   * Devuelve true en caso de que el carrito contenga un paquete que
   * se refiera al mismo producto, y devuelve false en caso contrario.
   *
   *@param $nomprod string  El nombre del producto que se busca.
   *
   *@return         boolean devuelve true en caso de existir el producto dentro 
   *                        del carrito, y devuelve false en caso contrario.
   */
  public function tieneProducto($nomprod)
  {
    foreach( $this->paquetes as $paquete)
      if( !strcmp($paquete->getProducto()->getNombre(),$nomprod))
        return true;

    return false; 
  }

  /*
   * devuelve true si el carrito esta vacio, o false
   *  en caso contrario
   */
  public function isEmpty()
  {
    if(0 == sizeof($this->paquetes))
      return true;
    return false;
  }

  /**
   * Elimina cualquier informacion relacionada a formas de pago.
   */
  public function borrarPagos()
  {
    $pago = $this->pago;
    unset($this->pago);
    
    //elimina la informacion de pagos y anula la orden
    Doctrine_Core::getTable('Pago')->eliminarPago($pago, true);
  }

  public function hasPago()
  {
    return isset($this->pago);
  }

  /**
   * Se vacia el carrito, dejandolo sin paquetes y sin informacion
   * de pagos.
   */
  public function vaciar()
  {
    /*
    foreach($this->paquetes as $key => $paquete) 
    {
      unset($this->paquetes[$key]);
    }
    */
    
    $this->paquetes = array();

    $this->precio_total = 0;

    //unset($this->pago);
    $this->pago = null;
  }

}
